package com.youlu.campus.admin.community.service;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.admin.auth.entity.SystemUser;
import com.youlu.campus.admin.community.entity.ActivityAclConfig;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.VO.req.ActivityAclConfigQueryVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * @author : [dengbo]
 * @className : ActivityAclConfigService
 * @description : [活动权限控制]
 * @createTime : [2023/7/11 17:26]
 */
@Service
@Slf4j
public class ActivityAclConfigService {

    @Autowired
    private MongoTemplate mongoTemplate;

    public ActivityAclConfig getConfig(String userId, String source) {
        return mongoTemplate.findOne(new Query(Criteria.where("userId").is(userId).and("source").is(source)), ActivityAclConfig.class);
    }

    public boolean checkActivity(String activityId, String userId) {
        ActivityInfo activityInfo = mongoTemplate.findById(activityId, ActivityInfo.class);
        if (activityInfo == null) {
            return false;
        }
        return userId.equals(activityInfo.getCreatorId());
    }

    public Page<ActivityAclConfig> list(ActivityAclConfigQueryVO req) {
        log.info(":>>> 开始获取活动权限列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取活动权限列表参数错误:req 为空");
            throw new BusinessException("获取活动权限列表参数错误");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getUserId())) {
            query.addCriteria(Criteria.where("userId").is(req.getUserId()));
        }
        if (StringUtils.isNotBlank(req.getType())) {
            query.addCriteria(Criteria.where("type").is(req.getType()));
        }
        if (StringUtils.isNotBlank(req.getSource())) {
            Pattern pattern = Pattern.compile("^.*" + req.getSource() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("source").regex(pattern));
        }
        if (StringUtils.isNotBlank(req.getDesc())) {
            Pattern pattern = Pattern.compile("^.*" + req.getDesc() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("desc").regex(pattern));
        }
        if (StringUtils.isNotBlank(req.getUserName())) {
            query.addCriteria(Criteria.where("userName").is(req.getUserName()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, ActivityAclConfig.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<ActivityAclConfig> infos = mongoTemplate.find(query.with(pageRequest), ActivityAclConfig.class);
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    public ActivityAclConfig findOne(String id) {
        return mongoTemplate.findOne(new Query(Criteria.where("id").is(id)), ActivityAclConfig.class);
    }

    public boolean create(@NotNull ActivityAclConfig req) {
        checkCreate(req.getUserId(), req.getSource(), req.getType());
        req.setId(null);
        req.setCreatedTime(new Date());
        if (StringUtils.isNotBlank(req.getUserId())) {
            SystemUser user = getUser(req.getUserId());
            if (Objects.nonNull(user)) {
                req.setUserName(user.getLoginName());
                req.setUserRealName(user.getRealName());
            }
        }
        req = mongoTemplate.insert(req);
        if (StringUtils.isNotBlank(req.getId())) {
            return true;
        }
        return false;
    }

    public boolean update(ActivityAclConfig req) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        boolean toUpdate = false;
        if (StringUtils.isNotBlank(req.getDesc())) {
            update.set("desc", req.getDesc());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(req.getType())) {
            update.set("type", req.getType());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(req.getSource())) {
            update.set("source", req.getSource());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getActivityIdList()) && !req.getActivityIdList().isEmpty()) {
            update.set("activityIdList", req.getActivityIdList());
            toUpdate = true;
        }
        if (toUpdate) {
            update.set("updatedTime", new Date());
            UpdateResult result = mongoTemplate.updateFirst(query, update, ActivityAclConfig.class);
            return result.getModifiedCount() > 0 ? true : false;
        }
        return true;
    }

    public boolean delete(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        DeleteResult result = mongoTemplate.remove(query, ActivityAclConfig.class);
        return result.getDeletedCount() > 0 ? true : false;
    }

    private SystemUser getUser(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(userId));
        return mongoTemplate.findOne(query, SystemUser.class);
    }

    private void checkCreate(String userId, String source, String type) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("source").is(source).and("type").is(type));
        boolean e = mongoTemplate.exists(query, ActivityAclConfig.class);
        if (e) {
            log.error(":>>> 改活动资源已经存在，请勿重复添加");
            throw new BusinessException("改活动资源已经存在，请勿重复添加");
        }
    }
}
